#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<signal.h>
#include"StdTcp.h"

struct TcpServer
{
    int sock;
};

TcpS *InitTcpServer(const char *ip, short int port)
{
    TcpS *s=(TcpS *)malloc(sizeof(TcpS));
    if(s==NULL)
    {
        printf("InitTcpServer malloc error!\n");
        free(s);
        return NULL;
    }
    s->sock=socket(AF_INET,SOCK_STREAM,0);  //tcp的套接字获取方式
    if(s->sock<0)
    {
        perror("socket:");
        free(s);
        return NULL;
    }

    int isUse=1;
    if(setsockopt(s->sock,SOL_SOCKET,SO_REUSEADDR,&isUse,4)!=0)
    {
        perror("setsockopt:");
        free(s);
        return NULL;
    }

    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=inet_addr(ip);
    if(bind(s->sock,(struct sockaddr *)&addr,sizeof(addr))!=0)
    {
        perror("bind:");
        free(s);
        return NULL;
    }

    if(listen(s->sock,10)!=0)
    {
        perror("listen:");
        free(s);
        return NULL;
    }
    return s;
}

void ClearTcpServer(TcpS *s)
{
    close(s->sock);
    free(s);
}

void TcpServerSend(int ClientSock, void *ptr, size_t size)
{
    if(send(ClientSock,ptr,size,0)<0)
    {
        perror("TcpServerSend:");
        return;
    }  
}

void TcpServerRecv(int ClientSock, void *ptr, size_t size)
{
    if(recv(ClientSock,ptr,size,0)<0)
    {
        perror("TcpServerRecv:");
    }    
}

int TcpServerAccept(TcpS *s)
{
    struct sockaddr_in ClientAddr;
    socklen_t len;
    int acceptSock = accept(s->sock,(struct sockaddr *)&ClientAddr,&len);
    if(acceptSock<0)
    {
        perror("accept:");
        return -1;
    }
    return acceptSock;
}

struct TcpClient
{
    int sock;
};

TcpC *InitTcpClient(const char *ServerIp, short int ServerPort)
{
    TcpC *c=(TcpC *)malloc(sizeof(TcpC));
    if(c==NULL)
    {
        printf("InitTcpClient malloc error!\n");
        free(c);
        return NULL;
    }
    c->sock=socket(AF_INET,SOCK_STREAM,0);  //tcp的套接字获取方式
    if(c->sock<0)
    {
        perror("socket:");
        free(c);
        return NULL;
    }

    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(ServerPort);
    addr.sin_addr.s_addr=inet_addr(ServerIp);
    if(connect(c->sock,(struct sockaddr *)&addr,sizeof(addr))!=0)
    {
        perror("connect:");
        free(c);
        return NULL;
    }  
    return c; 
}

void ClearTcpClient(TcpC *c)
{
    close(c->sock);
    free(c);    
}

void TcpClientSend(TcpC *c, void *ptr, size_t size)
{
    if(send(c->sock,ptr,size,0)<0)
    {
        perror("TcpClientSend:");
        return;
    }
}

void TcpClientRecv(TcpC *c, void *ptr, size_t size)
{
    if(recv(c->sock,ptr,size,0)<0)
    {
        perror("TcpClientRecv:");
    }   
}
